#include "socketcomm.h"

SocketComm::SocketComm(QString ip, int port, QObject *parent)
    : QObject(parent)
    , main_ip(ip)
    , main_port(port)
{
    recbuffer.resize(1024 * 1024 * 2);
    recbuffer.fill(0);
    codec = QTextCodec::codecForName("System");
    if (!codec) {
        codec = QTextCodec::codecForName("GBK");
    }

    m_replyTimer = new QTimer(this);
    m_replyTimer->setSingleShot(true);
    connect(m_replyTimer, &QTimer::timeout, this, &SocketComm::onTimeout);
}

bool SocketComm::ConnectToMain()
{
    // if (m_socketMain) {
    //     m_socketMain->disconnectFromHost();
    //     m_socketMain->abort();
    //     m_socketMain->deleteLater();
    // }
    m_socketMain = new QTcpSocket(this);
    QHostAddress address(main_ip);

    // 连接
    m_socketMain->connectToHost(address, main_port);

    // 连接结果
    if (!m_socketMain->waitForConnected(500)) {
        qWarning() << "连接网口卡失败:" << main_ip << ":" << main_port
                   << "错误:" << m_socketMain->errorString();
        return false;
    }
    connect(m_socketMain, &QTcpSocket::readyRead, this, &SocketComm::onReadyRead);

    qDebug() << "连接网口卡成功:" << main_ip;
    return true;
}

void SocketComm::disConnectToMain()
{
    if (!m_socketMain) {
        qDebug() << "没有活动的网口卡连接可断开";
        return;
    }
    m_socketMain->disconnectFromHost();
    if (m_socketMain->state() != QAbstractSocket::UnconnectedState) {
        m_socketMain->waitForDisconnected(500);
    }
    m_socketMain->deleteLater();
    m_socketMain = nullptr;
    recbuffer.clear();
    qDebug() << "已断开网口卡连接:" << main_ip;
}

void SocketComm::onReadyRead()
{
    qDebug() << "收到消息！";
    m_replyTimer->stop(); // 停止超时计时器
    m_pendingCommand.clear(); // 清除等待命令
    // if (!m_socketMain || !m_socketMain->isValid()) return;
    if (m_socketMain->bytesAvailable() <= 0) {
        return;
    }

    QByteArray newData = m_socketMain->readAll();
    recbuffer.append(newData);
    // qDebug() << "累计收到数据长度：" << recbuffer.size();
    // qDebug() << "Parse recbuffer:" << recbuffer.toHex().toUpper();

    while(true) {
        // QString str = codec->toUnicode(recbuffer);
        // int index = str.indexOf("FF");
        int headerPos = recbuffer.indexOf("AA AB"); // 包头
        if (headerPos < 0) break;
        // 对齐,只包含有效部分
        recbuffer = recbuffer.mid(headerPos);
        int footerPos = recbuffer.indexOf("FF"); // 包尾
        if (footerPos == -1 || footerPos > recbuffer.size()) {
            break; // 包不完整
        }
        // QByteArray payload = recbuffer.mid(2, recbuffer.size() - 3); // 去掉头尾
        QString packet = QString::fromLatin1(recbuffer.left(footerPos));
        recbuffer.remove(0, footerPos);
        // qDebug() << packet;
        DataProcess(packet);
    }
    // m_pendingCommand.clear(); // 清除等待命令
}

void SocketComm::DataProcess(const QString &data)
{
    // // 去除首尾空格，并按空格拆分
    // QStringList parts = data.trimmed().split(' ', Qt::SkipEmptyParts);
    // if (parts.size() < 4) {
    //     qDebug() << "Invalid frame:" << data;
    //     return;
    // }

    // QString trimmedData = data.trimmed();
    // if (trimmedData.isEmpty()) {
    //     return;
    // }
    QString temp = data.left(8);
    QString temp1 = data.left(9);

    qDebug() << "Invalid frame:" << data;

    // ==================== 1. 光纤炉温度: AA AB AA XX XX BB YY YY FF ====================
    if (temp == "AA AB AA") {
        QString tempe1 = data.mid(9, 2) + data.mid(12, 2);
        QString tempe2 = data.mid(18, 2) + data.mid(21, 2);

        // bool ok1, ok2;
        // double tempe1d = tempe1.toDouble(&ok1) / 4096.0 * 3.3;
        // double tempe2d = tempe2.toDouble(&ok2) / 4096.0 * 3.3;
        // if (!ok1 || !ok2) {
        //     return;
        // }
        // tempe1d = (tempe1d - 0.1) / 2.9 * 20.0 + 15.0;
        // tempe2d = (tempe2d - 0.1) / 2.9 * 20.0 + 15.0;

        bool ok3, ok4;
        double tempe1d1 = tempe1.toDouble(&ok3);
        double tempe2d1 = tempe2.toDouble(&ok4);
        // qDebug() << "tempe1d1: " << tempe1d1;
        // qDebug() << "tempe2d1: " << tempe2d1;
        if (!ok3 || !ok4) {
            return;
        }
        emit SendTemAB(tempe1d1, tempe2d1);
    }

    // ==================== 2. 温度、湿度、气压: AA AB ZS XXXXYYYYZZZZ FF ====================
    if (temp == "AA AB ZS")
    {
        QString tempe1 = data.mid(9, 4);
        QString tempe2 = data.mid(13, 4);
        QString tempe3 = data.mid(17, 4);

        bool ok1, ok2, ok3;
        double env_temperature = tempe1.toDouble(&ok1) / 10.0;
        double env_humidity = tempe2.toDouble(&ok2) / 10.0;
        double env_pressure = tempe3.toDouble(&ok3) / 100000.0;
        if (!ok1 || !ok2 || !ok3) {
            return;
        }

        // g_disK = computeK(env_temperature, env_pressure, env_humidity);
        emit SendEnvThree(env_temperature, env_humidity, env_pressure);
    }

    // ==================== 3. 光开关: AA AB OS 0X ON FF ====================
    if (temp == "AA AB OS")
    {
        QString tempChannel = data.mid(9, 2);
        bool ok;
        int channelIndex = tempChannel.toInt(&ok);
        if (!ok) return;

        qDebug() << QString("光通道：%1开启").arg(channelIndex);
        emit SendLightChannelOn(channelIndex);
    }

    // ==================== 5. 调焦控制 (FUS) 返回 ====================
    if (temp1 == "AA AB FUS") {
        if (data.contains("FUS RDY")) {
            qDebug() << "调焦运动完成";
            isFocusing = true;
            emit SendFocusMove(isFocusing);
        }
        else if (data.contains("FUS SET OK")) {
            qDebug() << "调焦设定完成";
            emit SendFocusSetok(true);
        }
        else if (data.contains("FUS WARN")) {
            qDebug() << "调焦到达上限位警告";
            emit SendFocusWarn(true);
        }
        return;
    }

    // ==================== 6. 风扇控制器 (FAN) 返回 ====================
    if (temp1 == "AA AB FAN") {
        if (data.contains("FAN SET OK")) {
            qDebug() << "风扇控制器参数设置成功";
            emit SendFanSetok(true);
        }
        else if (data.contains("FAN RD")) {
            // 格式: AA AB FAN RD XXX FF
            QString tempStr = data.mid(13, 3);
            bool ok;
            int rawTemp = tempStr.toInt(&ok, 16);
            if (ok) {
                // double fanTemp = rawTemp;
                emit SendFanTem(rawTemp);
            }
        }
        return;
    }

    // ==================== 7. 激光器温度控制 (LAS) 返回 ====================
    if (temp1 == "AA AB LAS") {
        if (data.contains("LAS SET OK")) {
            qDebug() << "激光器温度设置成功";
            emit SendLaserTemSetok(true);
        }
        else if (data.contains("LAS RD")) {
            // 格式: AA AB LAS RD XXXXXXXXX FF (9位)
            int pos = data.indexOf("LAS RD") + 7;
            QString tempStr = data.mid(pos, 9).trimmed();
            bool ok;
            long long rawTemp = tempStr.toLongLong(&ok);
            if (ok) {
                double lasTemp = rawTemp / 100000.0;
                emit SendLaserTem(lasTemp);
            }
        }
        return;
    }

    // ==================== 8. 光纤炉温度控制（大） (FTC) 返回 ====================
    if (temp1 == "AA AB FTC") {
        if (data.contains("FTC SET OK")) {
            qDebug() << "光纤炉温度设置成功";
            emit SendStoveTemSetok(true);
        }
        else if (data.contains("FTC SET ERR")) {
            qDebug() << "光纤炉温度设置失败";
            emit SendStoveTemSetErr(true);
        }
        else if (data.contains("FTC RD")) {
            // 格式: AA AB FTC RD K XXXXXXXXX FF
            QStringList parts = data.split(' ', Qt::SkipEmptyParts);
            if (parts.size() >= 6) {
                QString channel = parts[4]; // K
                QString tempStr = parts[5]; // 数值
                bool ok;
                long long rawTemp = tempStr.toLongLong(&ok);
                if (ok) {
                    double ftcTemp = rawTemp / 100000.0;

                    bool ok1;
                    int cha = channel.toInt(&ok1, 16);
                    if (ok1) {
                        qDebug() << QString("光纤炉(大)通道: %1 温度: %2℃").arg(channel).arg(ftcTemp, 0, 'f', 2);
                        emit SendStoveTemRead(cha, ftcTemp);
                    }
                }
            }
        }
        else if (data.contains("FTC REPLY ERR")) {
            qDebug() << "光纤炉查询返回错误";
            emit SendStoveTemReadErr(true);
        }
        return;
    }

}

void SocketComm::sendCommand(const QByteArray &cmd)
{
    qDebug() << "Socket state before sending command:" << m_socketMain->state();
    if (m_socketMain && m_socketMain->state() == QAbstractSocket::ConnectedState) {
        m_socketMain->write(cmd);
        m_socketMain->flush();
        // QThread::sleep(3000);
        // qDebug() << "Sent:" << cmd.toHex();
        QString cmdString = QString::fromLatin1(cmd);
        qDebug() << "SentString:" << cmdString;
    } else {
        qDebug() << "Socket not connected, cannot send command.";
    }
}

void SocketComm::waitForReply(const QString &cmdId, int timeoutMs)
{
    m_pendingCommand = cmdId;
    m_replyTimer->start(timeoutMs);
}

void SocketComm::onTimeout()
{
    if (!m_pendingCommand.isEmpty()) {
        emit operationFailed(m_pendingCommand);
        m_pendingCommand.clear();
        qDebug() << "Command timeout:" << m_pendingCommand;
    }
}

// ========== 灯光控制 ==========
void SocketComm::setLaserOn(bool on)
{
    // QByteArray cmd = on ? "AA AB VOA_ON 00" : "AA AB VOA_OFF 00";
    // sendCommand(cmd);
    sendCommand(on ? CommandDefine::CK_APPENDIX_LASER_ON : CommandDefine::CK_APPENDIX_LASER_OFF);
}
void SocketComm::setRedLight(bool on)
{
    sendCommand(on ? CommandDefine::CK_APPENDIX_RED_ON : CommandDefine::CK_APPENDIX_RED_OFF);
}
void SocketComm::setGreenLight(bool on)
{
    sendCommand(on ? CommandDefine::CK_APPENDIX_GREEN_ON : CommandDefine::CK_APPENDIX_GREEN_OFF);
}
void SocketComm::setBlueLight(bool on)
{
    sendCommand(on ? CommandDefine::CK_APPENDIX_BLUE_ON : CommandDefine::CK_APPENDIX_BLUE_OFF);
}

// ========== 衰减器 ==========
void SocketComm::setVOAOn(bool on)
{
    sendCommand(on ? CommandDefine::CK_VOA_ON : CommandDefine::CK_VOA_OFF);
}
void SocketComm::setVOAVoltage(int voltage)
{
    if ((voltage < 0) || (voltage > 5000)) {
        qWarning() << "Invalid VOA voltage:" << voltage;
        return;
    }
    QByteArray cmd = CommandDefine::buildVOASetVoltage(voltage);
    sendCommand(cmd);
    waitForReply("VOA_SET_VOLTAGE");
}

// ========== 光开关 ==========
void SocketComm::selectOpticalChannel(int channel)
{
    if ((channel < 0) || (channel > 4)) {
        qWarning() << "Invalid optical channel:" << channel;
        return;
    }
    QByteArray cmd = CommandDefine::buildOpticalSwitch(channel);
    sendCommand(cmd);
    waitForReply("OPTICAL_SWITCH_" + QString::number(channel));
}

// ========== 调焦 ==========
void SocketComm::moveFocusAB() { sendCommand(CommandDefine::CK_FOCUS_AB); }
void SocketComm::moveFocusAC() { sendCommand(CommandDefine::CK_FOCUS_AC); }
void SocketComm::moveFocusAD() { sendCommand(CommandDefine::CK_FOCUS_AD); }
void SocketComm::moveFocusBC() { sendCommand(CommandDefine::CK_FOCUS_BC); }
void SocketComm::moveFocusBD() { sendCommand(CommandDefine::CK_FOCUS_BD); }
void SocketComm::moveFocusCD() { sendCommand(CommandDefine::CK_FOCUS_CD); }

// ========== FUS 控制 ==========
void SocketComm::startHome()
{
    sendCommand(CommandDefine::CK_FUS_HOME);
    waitForReply("FUS_HOME");
}
void SocketComm::startMotion()
{
    sendCommand(CommandDefine::CK_FUS_POS);
    waitForReply("FUS_MOTION_START");
}
void SocketComm::stopMotion()
{
    sendCommand(CommandDefine::CK_FUS_STOP);
}
void SocketComm::startPosition(double speed, double pos)
{
    QByteArray cmd = CommandDefine::buildFUSSetSpeedPos(speed, pos);
    sendCommand(cmd);
    waitForReply("FUS_POS");
}

// ========== 风扇 ==========
void SocketComm::setFanTemp(int startTemp, int fullTemp)
{
    if ((startTemp < 0) || (startTemp > 255) || (fullTemp < 0) || (fullTemp > 255)) {
        qWarning() << "Fan temp out of range:" << startTemp << fullTemp;
        return;
    }
    QByteArray cmd = CommandDefine::buildFANSetTemp(startTemp, fullTemp);
    sendCommand(cmd);
    waitForReply("FAN_SET_TEMP");
}
void SocketComm::readFanTemp()
{
    sendCommand(CommandDefine::CK_FAN_READ_TEMP);
    waitForReply("FAN_READ_TEMP");
}

// ========== 激光器温度 ==========
void SocketComm::setLaserTemp(double temp)
{
    if ((temp < -400.0) || (temp > 1000.0)) {
        qWarning() << "Laser temp out of range:" << temp;
        return;
    }
    QByteArray cmd = CommandDefine::buildLASSetTemp(temp);
    sendCommand(cmd);
    waitForReply("LAS_SET_TEMP");
}
void SocketComm::queryLaserTemp()
{
    sendCommand(CommandDefine::CK_LAS_QUERY_TEMP);
    waitForReply("LAS_QUERY_TEMP");
}

// ========== 光纤炉温度 (FTC) ==========
void SocketComm::setFurnaceTemp(int channel, double temp)
{
    if ((channel != 1) && (channel != 2)) {
        qWarning() << "Invalid FTC channel:" << channel;
        return;
    }
    if ((temp < -400.0) || (temp > 1000.0)) {
        qWarning() << "FTC temp out of range:" << temp;
        return;
    }
    QByteArray cmd = CommandDefine::buildFTCSetTemp(channel, temp);
    sendCommand(cmd);
    waitForReply("FTC_SET_TEMP_CH" + QString::number(channel));
}
void SocketComm::queryFurnaceTemp(int channel)
{
    if ((channel != 1) && (channel != 2)) return;
    QByteArray cmd = CommandDefine::buildFTCQueryTemp(channel);
    sendCommand(cmd);
    waitForReply("FTC_QUERY_TEMP_CH" + QString::number(channel));
}

// ========== 查询类 ==========
void SocketComm::queryEnvironment()
{
    sendCommand(CommandDefine::CK_ENV_QUERY);
    waitForReply("ENV_QUERY");
}

void SocketComm::queryFurnaceDualTemp()
{
    sendCommand(CommandDefine::CK_FURNACE_QUERY);
    waitForReply("FURNACE_DUAL_QUERY");
}
